package aom.example.security.controller;

import aom.example.security.domain.SelfUserEntity;
import aom.example.security.domain.SysMenuEntity;
import aom.example.security.domain.SysRoleEntity;
import aom.example.security.domain.vo.MenuVo;
import aom.example.security.service.SysMenuService;
import aom.example.security.service.SysRoleService;
import aom.example.security.util.SecurityUtil;
import bom.example.common.common.Results;
import bom.example.common.excetion.ResultExcetion;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import dom.example.cache.domain.SysIcon;
import dom.example.cache.service.SysIconService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author X.I.O
 * @title: MenuController
 * @projectName springboot
 * @description: TODO
 * @date 2021/10/27 19:01
 */
@Api(tags = {"菜单服务"})
@RestController
@RequestMapping("/menu")
public class MenuController {

    @Autowired
    private SysMenuService sysMenuService;

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("目录删除")
    @PostMapping("deletedictory/{id}")
    public JSONObject deleteDictoryController(@PathVariable("id")String id) throws ResultExcetion{
        SysMenuEntity sysMenuEntity=sysMenuService.getOne(new LambdaQueryWrapper<SysMenuEntity>()
        .isNotNull(SysMenuEntity::getDictory).eq(SysMenuEntity::getMenuId,id));
        if(sysMenuEntity==null){
            throw new ResultExcetion(1,"菜单数据不存在");
        }
        Integer count=sysMenuService.getBaseMapper().
                selectCount(new LambdaQueryWrapper<SysMenuEntity>().isNull(SysMenuEntity::getDictory)
                .isNotNull(SysMenuEntity::getMenu).eq(SysMenuEntity::getMenu,sysMenuEntity.getDictory()));
        if(count>0){
            throw new ResultExcetion(1,"请先移除菜单下的子菜单再进行删除");
        }
        sysMenuService.removeById(sysMenuEntity.getMenuId());
        return Results.success("删除成功");
    }

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("菜单目录修改")
    @PostMapping("menudictoryupdate")
    public JSONObject updateMenuDictoryController(@RequestBody Map<String, String> map) throws ResultExcetion{
        String menuId=map.get("menuId");
        SysMenuEntity sysMenuEntity=sysMenuService.getOne(new LambdaQueryWrapper<SysMenuEntity>().isNotNull(SysMenuEntity::getDictory)
        .eq(SysMenuEntity::getMenuId,menuId));
        if(sysMenuEntity==null){
            throw new ResultExcetion(1,"目录不存在");
        }
        Boolean update=false;
        if(StringUtils.isNotBlank(map.get("name"))){
            sysMenuEntity.setName(map.get("name"));
            update=true;
        }
        if(StringUtils.isNotBlank(map.get("icon"))){
            String icon=map.get("icon");
            SysIcon sysIcon=sysIconService.getOne(new LambdaQueryWrapper<SysIcon>()
            .eq(SysIcon::getId,icon));
            if(sysIcon!=null){
                sysMenuEntity.setIcon(sysIcon.getIcon());
                update=true;
            }
        }
        if(update){
            sysMenuService.updateById(sysMenuEntity);
        }
        return Results.success("修改成功");
    }

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("获取单个目录")
    @PostMapping("getmenudictoryone/{id}")
    public JSONObject getDictoryMenuController(@PathVariable("id")String id) throws ResultExcetion{
        Map<String, Object> map=sysMenuService.getMap(new LambdaQueryWrapper<SysMenuEntity>().isNotNull(SysMenuEntity::getDictory)
                .eq(SysMenuEntity::getMenuId,id));
        if(map==null){
            throw new ResultExcetion(1,"获取单个失败");
        }
        String icon=String.valueOf(map.get("icon"));
        SysIcon sysIcon=sysIconService.getOne(new LambdaQueryWrapper<SysIcon>().eq(SysIcon::getIcon,icon));
        if(sysIcon!=null){
            map.put("icon_id",sysIcon.getId());
            map.put("icon_name",sysIcon.getIconName());
        }
        return Results.success(map);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("菜单删除")
    @PostMapping("/deleteMenu/{id}")
    @Transactional
    public JSONObject deleteMenuController(@PathVariable("id")String id) throws ResultExcetion{
        SysMenuEntity sysMenuEntity=sysMenuService.getBaseMapper()
                .selectOne(new LambdaQueryWrapper<SysMenuEntity>().isNotNull(SysMenuEntity::getMenu)
                .isNull(SysMenuEntity::getDictory).eq(SysMenuEntity::getMenuId,id));
        if(sysMenuEntity==null){
            throw new ResultExcetion(1,"菜单不存在");
        }
        sysMenuService.deleteSysMenuRole(String.valueOf(sysMenuEntity.getMenuId()));
        sysMenuService.removeById(sysMenuEntity.getMenuId());
        return Results.success("删除成功");
    }

    @ApiOperation("菜单列表")
    @PostMapping("/getMenulist")
    public JSONObject menuListPageController(@ApiParam("页码") @RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                             @ApiParam("条数")@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
                                             @ApiParam("关键字")@RequestParam(value = "keyword",required = false)String keyword){
        LambdaQueryWrapper<SysMenuEntity> lambdaQueryWrapper=new LambdaQueryWrapper();
        if(StringUtils.isNotBlank(keyword)){
            lambdaQueryWrapper.or().like(SysMenuEntity::getName,keyword);
            lambdaQueryWrapper.or().like(SysMenuEntity::getPermission,keyword);
        }
        lambdaQueryWrapper.orderByDesc(SysMenuEntity::getCreateDate);
        Page page=new Page(pageNum,pageSize);
        IPage<SysMenuEntity> sysMenuEntityIPage=sysMenuService.page(page,lambdaQueryWrapper);
        return Results.success(sysMenuEntityIPage.getRecords(),sysMenuEntityIPage.getTotal());
    }

    @ApiOperation("新增菜单")
    @PostMapping("/addmenu")
    public JSONObject addMenuController(@RequestBody MenuVo menuVo){
        SysMenuEntity sysMenuEntity=new SysMenuEntity();
        BeanUtils.copyProperties(menuVo,sysMenuEntity);
        sysMenuService.save(sysMenuEntity);
        return Results.success("新增成功");
    }

    @ApiOperation("菜单与角色")
    @PostMapping("menurole")
    public JSONObject menuController(@ApiParam("页码")@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                     @ApiParam("条数")@RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
                                     @ApiParam("关键字")@RequestParam(value = "keyword",required = false)String keyword){
        List<Map<String, Object>> objectMaps=sysMenuService.selectRoleMenuList(keyword,pageNum,pageSize);
        Integer count=sysMenuService.selectRoleMenuListCount(keyword);
        return Results.success(objectMaps,count);
    }

    @ApiOperation("后台菜单列表")
    @PostMapping("/menuList")
    public JSONObject menuListController(){
        //构建头部菜单查询
        LambdaQueryWrapper<SysMenuEntity> query=new LambdaQueryWrapper<>();
        query.isNotNull(SysMenuEntity::getDictory);
        //查询出头部菜单
        List<Map<String, Object>> navMenuList=sysMenuService.getBaseMapper()
                .selectMaps(query);
        //查询menuList
        List<Map<String, Object>> mapList=new ArrayList<>();
        navMenuList.forEach(e->{
            String dcitory=String.valueOf(e.get("dictory"));
            Map<String, Object> map=new HashMap<>();
            LambdaQueryWrapper<SysMenuEntity> query_1=new LambdaQueryWrapper<>();
            query_1.eq(SysMenuEntity::getMenu,dcitory);
            List<Map<String, Object>> maps=sysMenuService.getBaseMapper().selectMaps(query_1);
            map.put("idname",dcitory);
            map.put("menu",maps);
            mapList.add(map);
        });
        Map<String, Object> objectMap=new HashMap<>();
        objectMap.put("nav",navMenuList);
        objectMap.put("menuList",mapList);
        return Results.success(objectMap);
    }

    @Autowired
    private SysRoleService sysRoleService;

    @ApiOperation("获取用户菜单")
    @PostMapping("getUserMenuList")
    public JSONObject getUserMenuListController() throws ResultExcetion{
        SelfUserEntity userDetails = SecurityUtil.getUserInfo();
        if(userDetails==null){
            throw new ResultExcetion(1,"用户未登录");
        }
        //获取用户角色
        List<Map<String, Object>> entities=sysRoleService.selectRoleUserByUserId(String.valueOf(userDetails.getUserId()));
        List<String> strings=entities.stream().map(
                (e)->{
                   return String.valueOf(e.get("role_id"));
                }
        ).collect(Collectors.toList());
        List<Map<String, Object>> mapList=sysRoleService.selectRoleMenuList(strings);
        List<String> menus=mapList.stream().map(
                (e)->{
                    return String.valueOf(e.get("menu_id"));
                }
        ).collect(Collectors.toList());
        List<SysMenuEntity> sysMenuEntityList=sysMenuService.getBaseMapper()
                .selectBatchIds(menus);
        //选出唯一的菜单节点
       Set<String> strings1=sysMenuEntityList.stream().filter(e->{
           return e.getDictory()==null && e.getMenu()!=null;
       }).map(SysMenuEntity::getMenu)
               .collect(Collectors.toSet());
       Iterator<String>stringIterator=strings1.iterator();
       List<SysMenuEntity> list=new ArrayList<>(strings1.size());
       //获取对应菜单
       List<Map<String, Object>> maps=new ArrayList<>();
       while (stringIterator.hasNext()){
           Map<String, Object> map=new HashMap<>(5);
           String dictory=stringIterator.next();
           List<SysMenuEntity> entities1=sysMenuEntityList.stream()
                   .filter(e->{
                           return e.getMenu()!=null && e.getDictory()==null && e.getMenu().equals(dictory);
                       }).collect(Collectors.toList());
           map.put("idname",dictory);
           map.put("menu",entities1);
           maps.add(map);

           SysMenuEntity sysMenuEntity=sysMenuService.getBaseMapper()
                   .selectOne(new LambdaQueryWrapper<SysMenuEntity>().isNotNull(SysMenuEntity::getDictory)
                           .eq(SysMenuEntity::getDictory,dictory));
           list.add(sysMenuEntity);
       }
        Map<String, Object> objectMap=new HashMap<>();
        objectMap.put("nav",list);
        objectMap.put("menuList",maps);
        objectMap.put("username",userDetails.getUsername());
        return Results.success(objectMap);
    }


    /**
     * 角色菜单授权
     * @param pageNum 页码
     * @param pageSize 条数
     * @param keyword 关键字
     * @return  授权列表
     */
    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("角色菜单授权列表")
    @PostMapping("menurolelist")
    public JSONObject menuRoleListController(@RequestParam("pageNum")Integer pageNum,
                                             @RequestParam("pageSize")Integer pageSize,
                                             @RequestParam("roleId")String roleid,
                                             @RequestParam(value = "keyword",required = false)String keyword){
        IPage<Map<String, Object>> page=sysRoleService.selectRoleMenu(roleid,keyword,pageNum,pageSize);
        page.getRecords().forEach(e->{
            if(e.get("mid")==null){
                e.put("code",0);
            }else {
                e.put("code",1);
            }
        });
        return Results.success(page.getRecords(),page.getTotal());
    }



    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("菜单目录列表")
    @PostMapping("menuDictory")
    public JSONObject menuDictoryController(@RequestParam("pageNum")Integer pageNum,
                                            @RequestParam("pageSize")Integer pageSize,
                                            @RequestParam("keyword")String keyword){
        LambdaQueryWrapper<SysMenuEntity> query=new LambdaQueryWrapper<>();
        query.isNotNull(SysMenuEntity::getDictory);
        if(StringUtils.isNotBlank(keyword)){
            query.like(SysMenuEntity::getDictory,keyword);
            query.or().like(SysMenuEntity::getName,keyword);
        }
        Page page1=new Page(pageNum,pageSize);
        IPage<SysMenuEntity> sysMenuEntityIPage=sysMenuService.getBaseMapper()
                .selectPage(page1,query);
        return Results.success(sysMenuEntityIPage.getRecords(),sysMenuEntityIPage.getTotal());
    }

    @Autowired
    private SysIconService sysIconService;

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("后台菜单获取单个")
    @PostMapping("sysmenuOne/{id}")
    public JSONObject getSysMenuOneController(@PathVariable("id")Integer id){
        Map<String, Object> map=sysMenuService.getMap(new LambdaQueryWrapper<SysMenuEntity>()
        .isNull(SysMenuEntity::getDictory).isNotNull(SysMenuEntity::getMenu)
        .eq(SysMenuEntity::getMenuId,id));
        String icon=String.valueOf(map.get("icon"));
        SysIcon sysIcon=sysIconService.getBaseMapper().selectOne(new LambdaQueryWrapper<SysIcon>()
        .eq(SysIcon::getIcon,icon));
        map.put("icon_id",sysIcon.getId());
        map.put("icon_name",sysIcon.getIconName());
        String dictoryMenu=String.valueOf(map.get("menu"));
        SysMenuEntity sysMenuEntity=sysMenuService.getBaseMapper().selectOne(new LambdaQueryWrapper<SysMenuEntity>()
        .isNotNull(SysMenuEntity::getDictory).eq(SysMenuEntity::getDictory,dictoryMenu));
        if(sysMenuEntity!=null){
            map.put("dictoryid",sysMenuEntity.getMenuId());
            map.put("dictryname",sysMenuEntity.getName());
        }
        return Results.success(map);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("sysmenuupdate")
    @ApiOperation("菜单修改")
    public JSONObject updateSysmenuController(@RequestBody Map<String, String> map)throws ResultExcetion{
        String id=map.get("menuId");
        SysMenuEntity sysMenuEntity=sysMenuService.getBaseMapper().selectOne(new LambdaQueryWrapper<SysMenuEntity>()
        .isNull(SysMenuEntity::getDictory).isNotNull(SysMenuEntity::getMenu).eq(SysMenuEntity::getMenuId,id));

        if(sysMenuEntity==null){
            throw new ResultExcetion(1,"菜单信息不存在");
        }
        Boolean updateFlag=false;
        //修改菜单名
        if( StringUtils.isNotBlank(map.get("name"))){
            sysMenuEntity.setName(map.get("name"));
            updateFlag=true;
        }
        //修改权限
        if(StringUtils.isNotBlank(map.get("permission"))){
            sysMenuEntity.setPermission(map.get("permission"));
            updateFlag=true;
        }
        //修改菜单地址
        if(StringUtils.isNotBlank(map.get("menuUrl"))){
            sysMenuEntity.setMenuUrl(map.get("menuUrl"));
            updateFlag=true;
        }
        //修改目录
        if(StringUtils.isNotBlank(map.get("dictory"))){
            String dictory=map.get("dictory");
            SysMenuEntity sys=sysMenuService.getOne(new LambdaQueryWrapper<SysMenuEntity>()
            .isNotNull(SysMenuEntity::getDictory).eq(SysMenuEntity::getDictory,dictory));
            if(sys!=null){
                sysMenuEntity.setMenu(dictory);
                updateFlag=true;
            }
        }
        //修改图标
        if(StringUtils.isNotBlank(map.get("icon"))){
            String icon=map.get("icon");
            SysIcon sysIcon=sysIconService.getById(icon);
            if(sysIcon!=null){
                sysMenuEntity.setIcon(sysIcon.getIcon());
            }
        }
        if(updateFlag){
            sysMenuService.updateById(sysMenuEntity);
        }
        return Results.success("修改成功");
    }


    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("后台菜单列表")
    @PostMapping("sysmenulist")
    public JSONObject sysMenuListController(@RequestParam("pageNum")Integer pageNum,
                                            @RequestParam("pageSize")Integer pageSize,
                                            @RequestParam("keyword")String keyword){
        LambdaQueryWrapper<SysMenuEntity> query=new LambdaQueryWrapper<>();
        query.isNotNull(SysMenuEntity::getMenu).isNull(SysMenuEntity::getDictory);
        if(StringUtils.isNotBlank(keyword)){
            query.like(SysMenuEntity::getMenu,keyword);
            query.or().like(SysMenuEntity::getName,keyword);
        }
        Page page1=new Page(pageNum,pageSize);
        query.orderByDesc(SysMenuEntity::getCreateDate);
        IPage<Map<String, Object>> mapIPage=sysMenuService.pageMaps(page1,query);
        List<Map<String, Object>> mapList=mapIPage.getRecords();
        mapList.forEach(e->{
            String menu=String.valueOf(e.get("menu"));
            SysMenuEntity sysMenuEntity=sysMenuService.getOne(new LambdaQueryWrapper<SysMenuEntity>().eq(SysMenuEntity::getDictory,menu));
            if(sysMenuEntity!=null){
                e.put("dictoryName",sysMenuEntity.getName());
            }else {
                e.put("dictoryName","暂无所属目录");
            }
        });
        return Results.success(mapList,mapIPage.getTotal());
    }


    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("后台菜单添加目录")
    @PostMapping("addDcitory")
    public JSONObject addDictory(@RequestBody Map<String, String> map) throws ResultExcetion{
        //目录名称
        String name=String.valueOf(map.get("name"));
        //图标名称
        String icon=String.valueOf(map.get("icon"));
        SysIcon sysIcon=sysIconService.getById(icon);
        String idMenu=String.valueOf(map.get("idMenu"));
        String dictory=String.valueOf(map.get("dictory"));
        LambdaQueryWrapper<SysMenuEntity> query=new LambdaQueryWrapper<>();
        query.eq(SysMenuEntity::getDictory,dictory);
        SysMenuEntity sysMenuEntityOne=sysMenuService.getBaseMapper().selectOne(query);
        if(sysMenuEntityOne!=null){
            throw new ResultExcetion(1,"目录路径已存在");
        }
        SysMenuEntity sysMenuEntity=new SysMenuEntity();
        sysMenuEntity.setDictory(dictory);
        sysMenuEntity.setIcon(sysIcon.getIcon());
        sysMenuEntity.setMenu(idMenu);
        sysMenuEntity.setName(name);
        sysMenuEntity.setCreateDate(new Date());
        sysMenuService.save(sysMenuEntity);
        return Results.success("目录添加成功");
    }

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("后台目录下拉列表")
    @PostMapping("dictoryList")
    public JSONObject dictoryController(){
        LambdaQueryWrapper<SysMenuEntity> query=new LambdaQueryWrapper<>();
        query.isNotNull(SysMenuEntity::getDictory);
        List<SysMenuEntity> sysMenuEntityList=sysMenuService.getBaseMapper()
                .selectList(query);
        List<Map<String, String>> list=new ArrayList<>(20);
        for (int i = 0; i <sysMenuEntityList.size() ; i++) {
            SysMenuEntity obj=sysMenuEntityList.get(i);
            Map<String, String> map=new HashMap<>(2);
            map.put("key",obj.getName());
            map.put("value",obj.getDictory());
            list.add(map);
        }
        return Results.success(list);
    }




    @PostMapping("addsystemMenu")
    @ApiOperation("后台系统菜单添加")
    @PreAuthorize("hasRole('ADMIN')")
    public JSONObject addSystemController(@RequestBody Map<String, String> map){
        //菜单名称
        String name=String.valueOf(map.get("name"));
        //系统权限
        String permisson=String.valueOf(map.get("permission"));
        //访问路径
        String url=String.valueOf(map.get("href"));
        //菜单图标
        String icon=String.valueOf(map.get("icon"));
        SysIcon sysIcon=sysIconService.getById(icon);
        if(sysIcon==null){
            icon="";
        }else {
            icon=sysIcon.getIcon();
        }
        //菜单所属目录
        String idmenu=String.valueOf(map.get("dictory"));

        SysMenuEntity sysMenuEntity=new SysMenuEntity();
        //设置名称
        sysMenuEntity.setName(name);
        //设置权限
        sysMenuEntity.setPermission(permisson);
        //设置访问地址
        sysMenuEntity.setMenuUrl(url);
        //设置图标
        sysMenuEntity.setIcon(icon);
        //设置目录
        sysMenuEntity.setMenu(idmenu);
        sysMenuEntity.setCreateDate(new Date());
        sysMenuService.save(sysMenuEntity);
        return Results.success("新增成功");
    }


}
